home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / libs / sphigs / sph_dos.lha / dos / sphsrc / mat3geom.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-11-26  |  4.8 KB  |  178 lines

  1. #include "HEADERS.h"
  2. /* Copyright 1988, Brown Computer Graphics Group.  All Rights Reserved. */
  3.  
  4. /* --------------------------------------------------------------------------
  5.  * This file contains routines that perform geometry-related operations
  6.  * on matrices.
  7.  * -------------------------------------------------------------------------*/
  8.  
  9. #include "mat3defs.h"
  10.  
  11. /* --------------------------  Static Routines    ---------------------------- */
  12.  
  13. /* -------------------------  Internal Routines  --------------------------- */
  14.  
  15. /* --------------------------  Public Routines    ---------------------------- */
  16.  
  17. /*
  18.  * This takes a matrix used to transform points, and returns a corresponding
  19.  * matrix that can be used to transform direction vectors (between points).
  20.  */
  21.  
  22. void
  23. MAT3direction_matrix(result_mat, mat)
  24. register MAT3mat result_mat, mat;
  25. {
  26.    register int i;
  27.  
  28.    MAT3copy(result_mat, mat);
  29.  
  30.    for (i = 0; i < 4; i++) result_mat[i][3] = result_mat[3][i] = 0.0;
  31.  
  32.    result_mat[3][3] = 1.0;
  33. }
  34.  
  35. /*
  36.  * This takes a matrix used to transform points, and returns a corresponding
  37.  * matrix that can be used to transform vectors that must remain perpendicular
  38.  * to planes defined by the points.  It is useful when you are transforming
  39.  * some object that has both points and normals in its definition, and you
  40.  * only have the transformation matrix for the points.    This routine returns
  41.  * FALSE if the normal matrix is uncomputable.    Otherwise, it returns TRUE.
  42.  *
  43.  * Spike sez: "This is the adjoint for the non-homogeneous part of the
  44.  *           transformation."
  45.  */
  46.  
  47. int
  48. MAT3normal_matrix(result_mat, mat)
  49. register MAT3mat result_mat, mat;
  50. {
  51.    register int ret;
  52.    MAT3mat    tmp_mat;
  53.  
  54.    MAT3direction_matrix(result_mat, mat);
  55.  
  56.    if (ret = MAT3invert(tmp_mat, tmp_mat)) MAT3transpose(result_mat, tmp_mat);
  57.  
  58.    return(ret);
  59. }
  60.  
  61. /*
  62.  * Sets the given matrix to be a scale matrix for the given vector of
  63.  * scale values.
  64.  */
  65.  
  66. void
  67. MAT3scale(result_mat, scale)
  68. MAT3mat result_mat;
  69. MAT3vec scale;
  70. {
  71.    MAT3identity(result_mat);
  72.  
  73.    result_mat[0][0] = scale[0];
  74.    result_mat[1][1] = scale[1];
  75.    result_mat[2][2] = scale[2];
  76. }
  77.  
  78. /*
  79.  * Sets up a matrix for a rotation about an axis given by the line from
  80.  * (0,0,0) to axis, through an angle (in radians).
  81.  * Looking along the axis toward the origin, the rotation is counter-clockwise.
  82.  */
  83.  
  84. #define SELECT    .7071    /* selection constant (roughly .5*sqrt(2) */
  85.  
  86. void
  87. MAT3rotate(result_mat, axis, angle_in_radians)
  88. MAT3mat result_mat;
  89. MAT3vec axis;
  90. double    angle_in_radians;
  91. {
  92.    MAT3vec    naxis,    /* Axis of rotation, normalized         */
  93.         base2,    /* 2nd unit basis vec, perp to axis        */
  94.         base3;    /* 3rd unit basis vec, perp to axis & base2    */
  95.    double    dot;
  96.    MAT3mat    base_mat,    /* Change-of-basis matrix        */
  97.         base_mat_trans; /* Inverse of c-o-b matrix        */
  98.    register int i;
  99.  
  100.    /* Step 1: extend { axis } to a basis for 3-space: { axis, base2, base3 }
  101.     * which is orthonormal (all three have unit length, and all three are
  102.     * mutually orthogonal). Also should be oriented, i.e. axis cross base2 =
  103.     * base3, rather than -base3.
  104.     *
  105.     * Method: Find a vector linearly independent from axis. For this we
  106.     * either use the y-axis, or, if that is too close to axis, the
  107.     * z-axis. 'Too close' means that the dot product is too near to 1.
  108.     */
  109.  
  110.    MAT3_COPY_VEC(naxis, axis);
  111.    MAT3_NORMALIZE_VEC(naxis, dot);
  112.  
  113.    if (dot == 0.0) {
  114.       ERR_ERROR(MAT3_errid, ERR_SEVERE,
  115.            (ERR_S, "Zero-length axis vector given to MAT3rotate"));
  116.       return;
  117.    }
  118.  
  119.    MAT3perp_vec(base2, naxis, TRUE);
  120.    MAT3cross_product(base3, naxis, base2);
  121.  
  122.    /* Set up the change-of-basis matrix, and its inverse */
  123.    MAT3identity(base_mat);
  124.    MAT3identity(base_mat_trans);
  125.    MAT3identity(result_mat);
  126.  
  127.    for (i = 0; i < 3; i++){
  128.       base_mat_trans[i][0] = base_mat[0][i] = naxis[i];
  129.       base_mat_trans[i][1] = base_mat[1][i] = base2[i];
  130.       base_mat_trans[i][2] = base_mat[2][i] = base3[i];
  131.    }
  132.  
  133.    /* If T(u) = uR, where R is base_mat, then T(x-axis) = naxis,
  134.     * T(y-axis) = base2, and T(z-axis) = base3. The inverse of base_mat is
  135.     * its transpose.  OK?
  136.     */
  137.  
  138.    result_mat[1][1] =    result_mat[2][2] = cos(angle_in_radians);
  139.    result_mat[2][1] = -(result_mat[1][2] = sin(angle_in_radians));
  140.  
  141.    MAT3mult(result_mat, base_mat_trans, result_mat);
  142.    MAT3mult(result_mat, result_mat,    base_mat);
  143. }
  144.  
  145. /*
  146.  * Sets the given matrix to be a translation matrix for the given vector of
  147.  * translation values.
  148.  */
  149.  
  150. void
  151. MAT3translate(result_mat, trans)
  152. MAT3mat result_mat;
  153. MAT3vec trans;
  154. {
  155.    MAT3identity(result_mat);
  156.  
  157.    result_mat[3][0] = trans[0];
  158.    result_mat[3][1] = trans[1];
  159.    result_mat[3][2] = trans[2];
  160. }
  161.  
  162. /*
  163.  * Sets the given matrix to be a shear matrix for the given x and y shear
  164.  * values.
  165.  */
  166.  
  167. void
  168. MAT3shear(result_mat, xshear, yshear)
  169. MAT3mat result_mat;
  170. double    xshear, yshear;
  171. {
  172.    MAT3identity(result_mat);
  173.  
  174.    result_mat[2][0] = xshear;
  175.    result_mat[2][1] = yshear;
  176. }
  177.  
  178.